<template>
  <button id="connectButton" name="connectButton" class="buttonleft">Connect</button>
  <button id="disconnectButton" name="disconnectButton" class="buttonright" disabled>
    Disconnect
  </button>
  <div class="messagebox">
    <label for="message">Enter a message:
      <input type="text" name="message" id="message" placeholder="Message text" size="60" maxlength="120" disabled />
    </label>
    <button id="sendButton" name="sendButton" class="buttonright" disabled>Send</button>
  </div>
  <div class="messagebox" id="receivebox">
    <p>Messages received:</p>
  </div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue'
var connectButton: HTMLButtonElement
var disconnectButton: HTMLButtonElement
var sendButton: HTMLButtonElement
var messageInputBox: HTMLInputElement
var receiveBox: Element
var localConnection: RTCPeerConnection | null
var sendChannel: RTCDataChannel | null
var remoteConnection: RTCPeerConnection | null
// Set event listeners for user interface widgets
onMounted(() => {
  connectButton = document.getElementById('connectButton') as HTMLButtonElement
  disconnectButton = document.getElementById('disconnectButton') as HTMLButtonElement
  sendButton = document.getElementById('sendButton') as HTMLButtonElement
  messageInputBox = document.getElementById('message') as HTMLInputElement
  receiveBox = document.getElementById('receivebox') as Element
  connectButton.addEventListener('click', connectPeers, false)
  disconnectButton.addEventListener('click', disconnectPeers, false)
  sendButton.addEventListener('click', sendMessage, false)
})
// 连接
function connectPeers() {
  localConnection = new RTCPeerConnection()
  sendChannel = localConnection.createDataChannel('sendChannel')
  remoteConnection = new RTCPeerConnection()
  // 连接状态变化
  // localConnection.onconnectionstatechange = function () {
  //   console.log(arguments)
  // }
  // 打开
  sendChannel.onopen = handleSendChannelStatusChange
  // 关闭
  sendChannel.onclose = handleSendChannelStatusChange

  remoteConnection.ondatachannel = receiveChannelCallback

  localConnection.onicecandidate = (e) =>
    !e.candidate || remoteConnection?.addIceCandidate(e.candidate).catch(handleAddCandidateError)

  remoteConnection.onicecandidate = (e) =>
    !e.candidate || localConnection?.addIceCandidate(e.candidate).catch(handleAddCandidateError)

  localConnection
    .createOffer()
    .then((offer) => localConnection?.setLocalDescription(offer))
    .then(() => remoteConnection?.setRemoteDescription(localConnection?.localDescription!!))
    .then(() => remoteConnection?.createAnswer())
    .then((answer) => remoteConnection?.setLocalDescription(answer))
    .then(() => localConnection?.setRemoteDescription(remoteConnection?.localDescription!!))
    .catch(handleCreateDescriptionError)
}

function handleCreateDescriptionError(error: any) {
  console.log('Unable to create an offer: ' + error.toString())
}

// Handle successful addition of the ICE candidate
// on the "local" end of the connection.

function handleLocalAddCandidateSuccess() {
  connectButton.disabled = true
}

// Handle successful addition of the ICE candidate
// on the "remote" end of the connection.

function handleRemoteAddCandidateSuccess() {
  disconnectButton.disabled = false
}

// Handle an error that occurs during addition of ICE candidate.

function handleAddCandidateError() {
  console.log('Oh noes! addICECandidate failed!')
}

// Handles clicks on the "Send" button by transmitting
// a message to the remote peer.

function sendMessage() {
  var message = messageInputBox.value
  sendChannel?.send(message)

  // Clear the input box and re-focus it, so that we're
  // ready for the next message.

  messageInputBox.value = ''
  messageInputBox.focus()
}

// Handle status changes on the local end of the data
// channel; this is the end doing the sending of data
// in this example.

function handleSendChannelStatusChange(event: Event) {
  if (sendChannel) {
    var state = sendChannel.readyState
    console.log(event.type)
    if (state === 'open') {
      messageInputBox.disabled = false
      messageInputBox.focus()
      sendButton.disabled = false
      disconnectButton.disabled = false
      connectButton.disabled = true
    } else {
      messageInputBox.disabled = true
      sendButton.disabled = true
      connectButton.disabled = false
      disconnectButton.disabled = true
    }
  }
}

// Called when the connection opens and the data
// channel is ready to be connected to the remote.
let receiveChannel: RTCDataChannel | null
function receiveChannelCallback(event: RTCDataChannelEvent) {
  receiveChannel = event.channel
  receiveChannel.onmessage = handleReceiveMessage
  receiveChannel.onopen = handleReceiveChannelStatusChange
  receiveChannel.onclose = handleReceiveChannelStatusChange
}

// Handle onmessage events for the receiving channel.
// These are the data messages sent by the sending channel.

function handleReceiveMessage(event: MessageEvent<any>) {
  var el = document.createElement('p')
  var txtNode = document.createTextNode(event.data)

  el.appendChild(txtNode)
  receiveBox.appendChild(el)
}

// Handle status changes on the receiver's channel.

function handleReceiveChannelStatusChange(event: Event) {
  console.log(event.type)
  if (receiveChannel) {
    console.log("Receive channel's status has changed to " + receiveChannel.readyState)
  }

  // Here you would do stuff that needs to be done
  // when the channel's status changes.
}

// Close the connection, including data channels if they're open.
// Also update the UI to reflect the disconnected status.

function disconnectPeers() {
  // Close the RTCDataChannels if they're open.

  sendChannel!!.close()
  receiveChannel!!.close()

  // Close the RTCPeerConnections

  localConnection!!.close()
  remoteConnection!!.close()

  sendChannel = null
  receiveChannel = null
  localConnection = null
  remoteConnection = null

  // Update user interface elements

  connectButton.disabled = false
  disconnectButton.disabled = true
  sendButton.disabled = true

  messageInputBox.value = ''
  messageInputBox.disabled = true
}

// Set up an event listener which will run the startup
// function once the page is done loading.

// window.addEventListener('load', startup, false)
</script>
